Packages

library(tidyverse)
library(ggrepel)
library(extraDistr)   # install.packages("extraDistr")
library(HDInterval)   # install.packages("HDAPerval")
library(tidybayes)    # install.packages("tidybayes")
library(bayesplot)    # install.packages("bayesplot")
library(modelr)
library(broom.mixed)  # install.packages("broom.mixed")
library(brms)         # install.packages("brms")
library(ggthemes)
library(patchwork)
library(ggokabeito)   # install.packages("ggokabeito")
theme_set(theme_minimal())

# Creating a theme function used for visualizations
theme_clean <- function() {
  theme_minimal(base_family = "Arial") +
    theme(panel.grid.minor = element_blank(),
          plot.title = element_text(face = "bold"),
          axis.title = element_text(face = "bold"),
          strip.text = element_text(face = "bold", size = rel(1), hjust = 0),
          strip.background = element_rect(fill = "grey80", color = NA),
          legend.title = element_text(face = "bold"))
}

Loading the models

model_Int <- base::readRDS(file = "Models/brms_Int.rds")
model_Nat <- base::readRDS(file = "Models/brms_Nat.rds")
model_articRate <- base::readRDS(file = "Models/brms_articRate.rds")
model_AAVS <- base::readRDS(file = "Models/brms_AAVS.rds")
model_M1s <- base::readRDS(file = "Models/brms_M1s.rds")
model_M1sh <- base::readRDS(file = "Models/brms_M1sh.rds")
model_M2s <- base::readRDS(file = "Models/brms_M2s.rds")
model_M2sh <- base::readRDS(file = "Models/brms_M2sh.rds")

Formatting info

textSize_plotTitle <- 9
textSize_plotSubtitle <- 9
textSize_axisTitle <- 9

01. Reliability

workingData_Int <- base::readRDS(file = "workingData/data_Int.RDS")
workingData_Nat <- base::readRDS(file = "workingData/data_Nat.RDS")

interRel_plotData <- rbind(
  workingData_Int$data %>%
    dplyr::select(c(
      gorilla_id,
      speaker_id,
      `Time Point` = time_point,
      Group = group,
      Sex = sex,
      age,
      rating
    )
    ) %>%
    dplyr::mutate(
      Measure = "Intelligibility"
    ),
  workingData_Nat$data %>%
    dplyr::select(c(
      gorilla_id,
      speaker_id,
      `Time Point` = time_point,
      Group = group,
      Sex = sex,
      age,
      rating
    )
    ) %>%
    dplyr::mutate(
      Measure = "Naturalness"
    )
) %>%
  dplyr::filter(gorilla_id != "10237851") %>%
  dplyr::group_by(speaker_id, `Time Point`, Group, Sex, age, Measure) %>%
  dplyr::summarise(M = mean(rating),
                   sd = sd(rating)) %>%
  dplyr::ungroup() %>%
  dplyr::mutate(`Time Point` = factor(`Time Point`,
                                      levels = c("before",
                                                 "sensors",
                                                 "after"),
                                      labels = c("Before Sensors",
                                                 "With Sensors",
                                                 "After Sensors")),
                Measure = factor(Measure,
                                 levels = c("Intelligibility",
                                            "Naturalness"),
                                 labels = c("Intelligibility Ratings",
                                            "Naturalness Ratings")),
                Group = factor(Group,
                               levels = c("Control",
                                          "PD"),
                               labels = c("Control",
                                          "PwPD")))
`summarise()` has grouped output by 'speaker_id', 'Time Point', 'Group', 'Sex', 'age'. You can override using the `.groups` argument.
interRel_plot <- interRel_plotData %>%
  ggplot() +
  aes(
    x = M,
    y = sd,
    color = Group,
    shape = `Time Point`
  ) +
  geom_point() +
  facet_wrap(~Measure) +
  labs(x = "Average Rating (Mean)",
       y = "Rating Variability (sd)",
       title = "Inter-listener Reliability",
       #subtitle = "The mean and standard deviation of ratings across speakers and time points."
       ) +
  ggokabeito::scale_color_okabe_ito(order = c(2,
                                             #5,
                                             #4,
                                             1)) +
  ggthemes::theme_clean() &
  theme(
    strip.text.x = element_text(hjust = 0, size = 12),
    strip.text.y = element_text(angle = 0),
    plot.background = element_blank(),
    #panel.margin=unit(.05, "lines"),
        panel.border = element_rect(color = "black", fill = NA, size = 1), 
        strip.background = element_rect(color = "black", size = 1),
    #panel.border = element_rect(color = "black", fill = NA, size = 1), 
    legend.position = "bottom",
    legend.box="vertical",
    legend.background = element_rect(color = NA),
    aspect.ratio = 1)
Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
Please use the `linewidth` argument instead.
interRel_plot

ggsave(plot = interRel_plot,
       file = "Figures/Fig_Inter-Listener Reliability.png",
       height = 5,
       width = 6.5,
       units = "in",
       scale = 1,
       bg = "white")

02. Artic Rate

Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_articRate <- model_articRate %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = 66.88,
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

plot_grandMean_articRate <- ggplot(data_posterior_articRate, 
                                   aes(x = .epred, y = time_point, fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted articulation rate (syl/s)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted articulation rate after\ncontrolling for speaker age and sex.") +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  #facet_grid(sex~.) +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle),
        #panel.border = element_rect(color = "grey", fill = NA)
        ) +
  guides(fill = guide_legend(nrow = 1))

ME: Timepoint x Group

robust_articRate <- rio::import("workingData/data_articRate.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_articRate <- model_articRate %>%
  emmeans::emmeans( ~ time_point | group, epred = TRUE, re_formula = NA, ) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_articRate %>%
  emmeans::emmeans( ~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise, group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_articRate <- base::rbind(data_meContrasts_articRate, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_articRate)

plot_RQ1_articRate <- ggplot(
  data_meContrasts_articRate %>%
    dplyr::filter(contrast == "sensors - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of sensors effects (syl/s)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_articRate


plot_RQ2_articRate <- ggplot(
  data_meContrasts_articRate %>%
    dplyr::filter(contrast == "after - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensor\neffects (syl/s)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_articRate


# Combined plot
plot_articRate <-  plot_grandMean_articRate + plot_RQ1_articRate + plot_RQ2_articRate +
  patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect"
                         ) +
  plot_annotation(title = "Articulation Rate", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_articRate

ggsave(
  plot = plot_articRate,
  filename = "Figures/Fig_articRate.png",
  height = 6,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

03. AAVS

Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_AAVS <- model_AAVS %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_AAVS$data$age),
      artic_rate = mean(model_AAVS$data$artic_rate),
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

plot_grandMean_AAVS <- ggplot(data_posterior_AAVS, aes(x = .epred, y = time_point, fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted AAVS (mel²)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted AAVS after controlling for\nspeaker age, sex, and articulation rate.") +
  scale_y_discrete(limits = rev) +
  #coord_cartesian(xlim = c(.65,1)) +
  theme_clean() +
  #facet_grid(sex~.) +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle),
        #panel.border = element_rect(color = "grey", fill = NA)
        ) +
  guides(fill = guide_legend(nrow = 1))
plot_grandMean_AAVS

ME: Timepoint x Group

robust_AAVS <- rio::import("workingData/data_AAVS.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_AAVS <- model_AAVS %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")  %>%
  dplyr::mutate(group = case_when(
      group == "PD" ~ "PwPD",
      group == "Control" ~ "Control"
    ))

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_AAVS %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")  %>%
  dplyr::mutate(group = case_when(
      group == "PD - Control" ~ "PwPD -\nControl"
    ))

data_meContrasts_AAVS <- base::rbind(data_meContrasts_AAVS, interaction_contrast) %>%
  base::merge(., robust_AAVS) %>%
  dplyr::mutate(
    robust = factor(robust, levels = c("not robust", "robust")))

#bayestestR::p_direction(data_meContrasts_AAVS)

plot_RQ1_AAVS <- ggplot(
  data_meContrasts_AAVS %>%
    dplyr::filter(contrast == "sensors - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of sensors effects (mel²)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_AAVS


plot_RQ2_AAVS <- ggplot(
  data_meContrasts_AAVS %>%
    dplyr::filter(contrast == "after - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensor\neffects (mel²)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_AAVS


# Combined plot
plot_AAVS <-  plot_grandMean_AAVS + plot_RQ1_AAVS + plot_RQ2_AAVS +
  patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
  plot_annotation(title = "Articulatory Acoustic Vowel Space", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_AAVS

ggsave(
  plot = plot_AAVS,
  filename = "Figures/Fig_AAVS.png",
  height = 6,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

04. M1

/s/ - Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M1s <- model_M1s %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_M1s$data$age),
      artic_rate = mean(model_M1s$data$artic_rate),
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

/s/ - ME: Timepoint x Group

robust_M1s <- rio::import("workingData/data_M1s.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M1s <- model_M1s %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M1s %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_M1s <- base::rbind(data_meContrasts_M1s, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_M1s) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

#bayestestR::p_direction(data_meContrasts_M1s)

/sh/ - Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M1sh <- model_M1sh %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_M1sh$data$age),
      artic_rate = mean(model_M1sh$data$artic_rate),
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

/sh/ - ME: Timepoint x Group

robust_M1sh <- rio::import("workingData/data_M1sh.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M1sh <- model_M1sh %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M1sh %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_M1sh <- base::rbind(data_meContrasts_M1sh, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_M1sh) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

#bayestestR::p_direction(data_meContrasts_M1sh)

Combined

Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M1 <- rbind(data_posterior_M1s %>%
                             dplyr::mutate(sound = "/s/"),
                           data_posterior_M1sh %>%
                             dplyr::mutate(sound = "/ʃ/"))

plot_grandMean_M1 <- ggplot(data_posterior_M1, 
                                   aes(x = .epred, y = time_point, 
                                       fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted M1 (kHz)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted M1 after controlling for\nspeaker age, sex, and articulation rate.") +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  facet_wrap(~sound, ncol = 1) +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle))  +
  guides(fill = guide_legend(nrow = 1))

ME: Timepoint x Group

data_meContrasts_M1 <- rbind(data_meContrasts_M1s %>%
                             dplyr::mutate(sound = "/s/"),
                           data_meContrasts_M1sh %>%
                             dplyr::mutate(sound = "/ʃ/"))

#bayestestR::p_direction(data_meContrasts_M1)

plot_RQ1_M1 <- ggplot(
  data_meContrasts_M1 %>%
    dplyr::filter(contrast == "sensors - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of sensors effects (kHz)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  facet_wrap(~sound, ncol = 1) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_M1


plot_RQ2_M1 <- ggplot(
  data_meContrasts_M1 %>%
    dplyr::filter(contrast == "after - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensor\neffects (kHz)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  facet_wrap(~sound, ncol = 1) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_M1


# Combined plot
plot_M1 <-  plot_grandMean_M1 + plot_RQ1_M1 + plot_RQ2_M1 +
  patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
  plot_annotation(title = "Spectral Center of Gravity (M1)", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_M1

ggsave(
  plot = plot_M1,
  filename = "Figures/Fig_M1.png",
  height = 7,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

05. M2

/s/ - Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M2s <- model_M2s %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_M2s$data$age),
      artic_rate = mean(model_M2s$data$artic_rate),
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

/s/ - ME: Timepoint x Group

robust_M2s <- rio::import("workingData/data_M2s.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M2s <- model_M2s %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M2s %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_M2s <- base::rbind(data_meContrasts_M2s, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_M2s) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

#bayestestR::p_direction(data_meContrasts_M2s)

/sh/ - Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M2sh <- model_M2sh %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_M2sh$data$age),
      artic_rate = mean(model_M2sh$data$artic_rate),
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    )
  )

/sh/ - ME: Timepoint x Group

robust_M2sh <- rio::import("workingData/data_M2sh.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M2sh <- model_M2sh %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M2sh %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_M2sh <- base::rbind(data_meContrasts_M2sh, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_M2sh) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

#bayestestR::p_direction(data_meContrasts_M2sh)

Combined

Expected Posteriors

# Generate expected predictions from the posterior
data_posterior_M2 <- rbind(data_posterior_M2s %>%
                             dplyr::mutate(sound = "/s/"),
                           data_posterior_M2sh %>%
                             dplyr::mutate(sound = "/ʃ/"))

plot_grandMean_M2 <- ggplot(data_posterior_M2, 
                                   aes(x = .epred, y = time_point, 
                                       fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted M2 (kHz)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted M2 after controlling for\nspeaker age, sex, and articulation rate.") +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  facet_wrap(~sound, ncol = 1) +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle))  +
  guides(fill = guide_legend(nrow = 1))

ME: Timepoint x Group

data_meContrasts_M2 <- rbind(data_meContrasts_M2s %>%
                             dplyr::mutate(sound = "/s/"),
                           data_meContrasts_M2sh %>%
                             dplyr::mutate(sound = "/ʃ/"))

#bayestestR::p_direction(data_meContrasts_M2)

plot_RQ1_M2 <- ggplot(
  data_meContrasts_M2 %>%
    dplyr::filter(contrast == "sensors - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of sensors effects (kHz)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  facet_wrap(~sound, ncol = 1) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_M2


plot_RQ2_M2 <- ggplot(
  data_meContrasts_M2 %>%
    dplyr::filter(contrast == "after - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensor\neffects (kHz)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  facet_wrap(~sound, ncol = 1) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_M2


# Combined plot
plot_M2 <-  plot_grandMean_M2 + plot_RQ1_M2 + plot_RQ2_M2 +
  patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
  plot_annotation(title = "Spectral Standard Deviation (M2)", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_M2

ggsave(
  plot = plot_M2,
  filename = "Figures/Fig_M2.png",
  height = 7,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

06. Intelligibility

Expected Posteriors

epsilon <- 1e-5
# Generate expected predictions from the posterior
data_posterior_Int <- model_Int %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_Int$data$age), # 66.91 yo
      artic_rate = mean(model_Int$data$artic_rate), # 4.85 syl/s
      trial_number = mean(model_Int$data$trial_number) # trial 9
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    ),
    .epred = (.epred - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .epred = .epred * nrow(.) / ((nrow(.) - 1) + .5),
    .epred = .epred * 100 # to turn it back to a scale of 0 - 100
  )

plot_grandMean_Int <- ggplot(data_posterior_Int, 
                                   aes(x = .epred, y = time_point, 
                                       fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted intelligibility rating (%)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted intelligibility rating after controlling\nfor speaker age, sex, articulation rate,\nand trial number.") +
  scale_y_discrete(limits = rev) +
  coord_cartesian(xlim = c(72,100)) +
  theme_clean() +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle),
        #panel.border = element_rect(color = "grey", fill = NA)
        ) +
  guides(fill = guide_legend(nrow = 1))

ME: Timepoint x Group

robust_Int <- rio::import("workingData/data_Int.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
epsilon <- 1e-5
data_meContrasts_Int <- model_Int %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::mutate(
    .value = (.value - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .value = .value * nrow(.) / ((nrow(.) - 1) + .5),
    .value = .value * 100
  ) %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_Int %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::mutate(
    .value = (.value - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .value = .value * nrow(.) / ((nrow(.) - 1) + .5),
    .value = .value * 100
  ) %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_Int <- base::rbind(data_meContrasts_Int, interaction_contrast) %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_Int) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

plot_RQ1_Int <- ggplot(
  data_meContrasts_Int %>%
    dplyr::filter(contrast == "sensors - before"),
  aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  # Text annotation for the Control and PwPD distributions
  annotate(
    'text',
    x = -.13*100, # Play around with the coordinates until you're satisfied
    y = 3.3,
    label = "Both Control and PwPD\nwere robustly less intelligbile\nwith EMA sensors on...",
    hjust = 0,
    size = 2,
    alpha = .8,
    color = "black"
  ) +
  # Arrow to the Control distribution
  annotate(
    'curve',
    x = -.095*100, # Play around with the coordinates until you're satisfied
    y = 3.1,
    xend = -.03*100,
    yend = 2.96,
    linewidth = .4,
    curvature = 0.2,
    arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
    alpha = 1,
    color = "darkgrey"
  ) +
  # Arrow to the PwPD distribution
  annotate(
    'curve',
    x = -.096*100, # Play around with the coordinates until you're satisfied
    y = 3.1,
    xend = -.065*100,
    yend = 2.3,
    linewidth = .4,
    curvature = 0.2,
    arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
    alpha = 1,
    color = "darkgrey"
  ) +
  # Text for the contrast distribution
  annotate(
    'text',
    x = -.07*100, # Play around with the coordinates until you're satisfied
    y = 0.73,
    label = "... but these effects\nwere robustly different\nbetween the groups.",
    hjust = 1,
    size = 2,
    alpha = .8,
    color = "black"
  ) +
    # Arrow to the contrast distribution
  annotate(
    'curve',
    x = -.065*100, # Play around with the coordinates until you're satisfied
    y = 0.73,
    xend = -.045*100,
    yend = .95,
    linewidth = .4,
    curvature = 0.2,
    arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
    alpha = 1,
    color = "darkgrey"
  ) +
  labs(
    x = "Average marginal effect of sensors effects (%)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_Int


plot_RQ2_Int <- ggplot(
  data_meContrasts_Int %>%
    dplyr::filter(contrast == "after - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensor\neffects (%)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_Int


# Combined plot
plot_Int <-  plot_grandMean_Int + plot_RQ1_Int + plot_RQ2_Int +
  patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
  plot_annotation(title = "Intelligibility", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_Int

ggsave(
  plot = plot_Int,
  filename = "Figures/Fig_Int.png",
  height = 6,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

07. Naturalness

Expected Posteriors

epsilon <- 1e-5
# Generate expected predictions from the posterior
data_posterior_Nat <- model_Nat %>%
  tidybayes::epred_draws(
    newdata = tidyr::expand_grid(
      group = c("Control", "PD"),
      time_point = c("before", "sensors", "after"),
      sex = c("Male", "Female"),
      age = mean(model_Nat$data$age), # 66.91 yo
      artic_rate = mean(model_Nat$data$artic_rate), # 4.85 syl/s
      trial_number = mean(model_Nat$data$trial_number) # trial 9
    ),
    re_formula = NA
  ) %>%
  group_by(.draw, group, time_point) %>%
  summarize(.epred = mean(.epred), .groups = "drop") %>%
  dplyr::mutate(
    group = factor(
      group,
      levels = c("Control", "PD"),
      labels = c("Control", "PwPD")
    ),
    #grouping = paste(sex, group, sep = " - "),
    #grouping = factor(grouping,
    #                  levels = c("Male - Control",
    #                             "Male - PwPD",
    #                             "Female - Control",
    #                             "Female - PwPD")),
    time_point = factor(
      time_point,
      levels = c("before", "sensors", "after"),
      labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
    ),
    .epred = (.epred - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .epred = .epred * nrow(.) / ((nrow(.) - 1) + .5),
    .epred = .epred * 100
  )

plot_grandMean_Nat <- ggplot(data_posterior_Nat, 
                                   aes(x = .epred, y = time_point, 
                                       fill = group)) +
  stat_halfeye(alpha = .9) +
  ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
  labs(x = "Predicted naturalness rating (%)", y = NULL,
       fill = "Group",
       title = "(a) Posterior Predictions",
       subtitle = "Predicted naturalness rating after controlling\nfor speaker age, sex, articulation rate,\nand trial number.") +
  scale_y_discrete(limits = rev) +
  coord_cartesian(xlim = c(0,100)) +
  theme_clean() +
  theme(legend.position = "bottom",
        axis.title = element_text(size = textSize_axisTitle),
        plot.title = element_text(size = textSize_plotTitle),
        plot.subtitle = element_text(size = textSize_plotSubtitle))  +
  guides(fill = guide_legend(nrow = 1))

ME: Timepoint x Group

robust_Nat <- rio::import("workingData/data_Nat.RDS")$pairwise %>%
  dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
epsilon <- 1e-5
data_meContrasts_Nat <- model_Nat %>%
  emmeans::emmeans(~ time_point | group,
                   epred = TRUE,
                   re_formula = NA,) %>%
  emmeans::contrast(method = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::mutate(
    .value = (.value - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .value = .value * nrow(.) / ((nrow(.) - 1) + .5),
    .value = .value * 100
  ) %>%
  dplyr::filter(contrast != "after - sensors")

# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_Nat %>%
  emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
  emmeans::contrast(interaction = "revpairwise") %>%
  gather_emmeans_draws() %>%
  dplyr::mutate(
    .value = (.value - epsilon) / (1 - 2 * epsilon),
    # Step 1 & 2: Reverse the offset and scaling
    .value = .value * nrow(.) / ((nrow(.) - 1) + .5),
    .value = .value * 100
  ) %>%
  dplyr::rename(contrast = time_point_revpairwise,
                group = group_revpairwise) %>%
  dplyr::filter(contrast != "after - sensors")

data_meContrasts_Nat <- base::rbind(data_meContrasts_Nat, interaction_contrast)  %>%
  dplyr::mutate(group = case_when(
    group == "PD" ~ "PwPD",
    group == "Control" ~ "Control",
    group == "PD - Control" ~ "PwPD -\nControl"
  )) %>%
  base::merge(., robust_Nat) %>%
  dplyr::mutate(robust = factor(robust,
                                levels = c("not robust",
                                           "robust")))

#bayestestR::p_direction(data_meContrasts_Nat)

plot_RQ1_Nat <- ggplot(
  data_meContrasts_Nat %>%
    dplyr::filter(contrast == "sensors - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of sensors effects (%)",
    y = NULL,
    title = "(b) Research Question 1",
    subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ1_Nat


plot_RQ2_Nat <- ggplot(
  data_meContrasts_Nat %>%
    dplyr::filter(contrast == "after - before"),
    aes(x = .value, y = group, fill = robust)
) +
  geom_vline(xintercept = 0, alpha = .3) +
  stat_halfeye(alpha = .9) +
  scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
                     drop = FALSE) +
  labs(
    x = "Average marginal effect of after-sensors\neffects (%)",
    y = NULL,
    title = "(c) Research Question 2",
    subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
    fill = "Robust at 95% HPD Interval & pd"
  ) +
  scale_y_discrete(limits = rev) +
  theme_clean() +
  theme(
    legend.position = "bottom",
    axis.title = element_text(size = textSize_axisTitle),
    plot.title = element_text(size = textSize_plotTitle),
    plot.subtitle = element_text(size = textSize_plotSubtitle)
  )

plot_RQ2_Nat


# Combined plot
plot_Nat <-  plot_grandMean_Nat + plot_RQ1_Nat + plot_RQ2_Nat +
  patchwork::plot_layout(ncol = 3,
                         heights = c(1),
                         guides = "collect") +
  plot_annotation(title = "Naturalness",
                  theme = theme_clean()) &
  theme(legend.position = "bottom")
plot_Nat

ggsave(
  plot = plot_Nat,
  filename = "Figures/Fig_Nat.png",
  height = 6,
  width = 10,
  unit = "in",
  scale = .9,
  bg = "white"
)

S01. Individual Variability

workingData_articRate <- base::readRDS(file = "workingData/data_articRate.RDS")
workingData_AAVS <- base::readRDS(file = "workingData/data_AAVS.RDS")
workingData_M1s <- base::readRDS(file = "workingData/data_M1s.RDS")
workingData_M1sh <- base::readRDS(file = "workingData/data_M1sh.RDS")
workingData_M2s <- base::readRDS(file = "workingData/data_M2s.RDS")
workingData_M2sh <- base::readRDS(file = "workingData/data_M2sh.RDS")
workingData_Int <- base::readRDS(file = "workingData/data_Int.RDS")
workingData_Nat <- base::readRDS(file = "workingData/data_Nat.RDS")

allData <- bind_rows(
  workingData_articRate$modelData %>%
    dplyr::mutate(measure = "Articulation Rate") %>%
    dplyr::rename(value = articRate),
  
  workingData_AAVS$modelData %>%
    dplyr::mutate(measure = "AAVS") %>%
    dplyr::rename(value = AAVS),
  
  workingData_M1s$modelData %>%
    dplyr::mutate(measure = "M1 for /s/") %>%
    dplyr::rename(value = M1s),
  
  workingData_M2s$modelData %>%
    dplyr::mutate(measure = "M2 for /s/") %>%
    dplyr::rename(value = M2s),
  
  workingData_M1sh$modelData %>%
    dplyr::mutate(measure = "M1 for /ʃ/") %>%
    dplyr::rename(value = M1sh),
  
  workingData_M2sh$modelData %>%
    dplyr::mutate(measure = "M2 for /ʃ/") %>%
    dplyr::rename(value = M2sh),
  
  workingData_Int$modelData %>%
    dplyr::mutate(measure = "Intelligibility",
                  Int = Int*100) %>%
    dplyr::rename(value = Int),
  
  workingData_Nat$modelData %>%
    dplyr::mutate(measure = "Naturalness",
                  Nat = Nat*100) %>%
    dplyr::rename(value = Nat)
) %>%
  dplyr::mutate(time_point = factor(time_point,
                                    levels = c("before",
                                               "sensors",
                                               "after"),
                                    labels = c("Before\nSensors",
                                               "With\nSensors",
                                               "After\nSensors")),
                measure = factor(measure,
                                 levels = c("Articulation Rate",
                                            "AAVS",
                                            "M1 for /s/",
                                            "M2 for /s/",
                                            "M1 for /ʃ/",
                                            "M2 for /ʃ/",
                                            "Intelligibility",
                                            "Naturalness"),
                                 labels = c("Articulation Rate (syl/s)",
                                            "AAVS (mel²)",
                                            "M1 for /s/ (kHz)",
                                            "M2 for /s/ (kHz)",
                                            "M1 for /ʃ/ (kHz)",
                                            "M2 for /ʃ/ (kHz)",
                                            "Intelligibility (%)",
                                            "Naturalness (%)")),
                group = factor(group,
                               levels = c("Control",
                                          "PD"),
                               labels = c("Control",
                                          "PwPD")),
                grouping = paste(sex, group, sep = " - "),
                grouping = factor(grouping,
                      levels = c("Male - Control",
                                 "Male - PwPD",
                                 "Female - Control",
                                 "Female - PwPD"))) %>%
  dplyr::group_by(measure, speaker_id, group, sex, grouping, age, time_point) %>%
  dplyr::summarise(value = mean(value)) %>%
  dplyr::ungroup()
`summarise()` has grouped output by 'measure', 'speaker_id', 'group', 'sex', 'grouping', 'age'. You can override using the `.groups` argument.
plotData <- bind_rows(
  allData %>%
    dplyr::mutate(plot = "All Data"),
  allData %>%
    dplyr::filter(time_point != "After\nSensors") %>%
    dplyr::mutate(plot = "Sensor Effects"),
  allData %>%
    dplyr::filter(time_point != "With\nSensors") %>%
    dplyr::mutate(plot = "After-Sensor Effects"),
) %>%
  dplyr::mutate(plot = factor(plot,
                              levels = c("All Data",
                                         "Sensor Effects",
                                         "After-Sensor Effects"),
                              labels = c("All Data",
                                         "Sensor Effects",
                                         "After-Sensor\nEffects"))) %>%
  dplyr::filter(plot != "All Data")

plot_rawData_sensorEffects <- plotData %>%
  dplyr::filter(plot == "Sensor Effects") %>%
  ggplot() +
  aes(x = time_point, y = value, color = group) +
  geom_line(aes(group = speaker_id), alpha = .3) +
  geom_line(
    data = plotData %>%
      dplyr::filter(plot == "Sensor Effects") %>%
      dplyr::group_by(measure, group, sex, time_point, plot) %>%
      dplyr::summarise(value = mean(value)),
    aes(group = group),
    alpha = .8,
    linewidth = 1.5
  ) +
  #geom_point(aes(shape = sex)) +
  ggokabeito::scale_color_okabe_ito(order = c(2,1)) +
  facet_grid(measure ~ sex, scales = "free", switch = "y") +
  labs(x = NULL,
       y = NULL,
       color = "Group",
       shape = "Sex",
       title = "Sensor Effects") +
  scale_x_discrete(expand=expansion(c(.35,.35))) +
  theme_clean() &
  theme(panel.border = element_rect(fill = NA, color = "black"),
        strip.background = element_rect(fill = "white", color = NA),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0, face="plain", hjust = 1),)
`summarise()` has grouped output by 'measure', 'group', 'sex', 'time_point'. You can override using the `.groups` argument.
plot_rawData_sensorEffects


plot_rawData_afterSensorEffects <- plotData %>%
  dplyr::filter(plot == "After-Sensor\nEffects") %>%
  ggplot() +
  aes(x = time_point, y = value, color = group) +
  geom_line(aes(group = speaker_id), alpha = .3) +
  geom_line(
    data = plotData %>%
      dplyr::filter(plot == "After-Sensor\nEffects") %>%
      dplyr::group_by(measure, group, sex, time_point, plot) %>%
      dplyr::summarise(value = mean(value)),
    aes(group = group),
    alpha = .8,
    linewidth = 1.5
  ) +
  #geom_point(aes(shape = sex)) +
  ggokabeito::scale_color_okabe_ito(order = c(2,1)) +
  facet_grid(measure ~ sex, scales = "free") +
  labs(x = NULL,
       y = NULL,
       color = "Group",
       shape = "Sex",
       title = "After-Sensor Effects") +
  scale_x_discrete(expand=expansion(c(.35,.35))) +
  theme_clean() &
  theme(panel.border = element_rect(fill = NA, color = "black"),
        #strip.background = element_rect(fill = "white", color = NA),
        strip.placement = "outside",
        #strip.text.y.left = element_text(angle = 0, face="plain", hjust = 1),
        strip.background = element_blank(),
        strip.text.y. = element_blank())
`summarise()` has grouped output by 'measure', 'group', 'sex', 'time_point'. You can override using the `.groups` argument.
plot_rawData_afterSensorEffects

plot_rawData <- plot_rawData_sensorEffects + plot_rawData_afterSensorEffects +
  patchwork::plot_layout(ncol = 2, #heights = c(1),
                         guides = "collect") +
  plot_annotation(title = "Raw Data", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
                  theme = theme_clean()) &
  theme(
    legend.position = "right",
    strip.background.right = element_blank(),
    strip.text.y.right = element_blank()
  )

ggsave(
  plot = plot_rawData,
  filename = "Figures/SupFig_rawData.png",
  height = 10,
  width = 9,
  unit = "in",
  scale = .9,
  bg = "white"
)

LS0tCnRpdGxlOiAiVm93ZWwgQXJ0aWMgaW4gUEQ6IFBsb3RzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIFBhY2thZ2VzCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KGV4dHJhRGlzdHIpICAgIyBpbnN0YWxsLnBhY2thZ2VzKCJleHRyYURpc3RyIikKbGlicmFyeShIREludGVydmFsKSAgICMgaW5zdGFsbC5wYWNrYWdlcygiSERBUGVydmFsIikKbGlicmFyeSh0aWR5YmF5ZXMpICAgICMgaW5zdGFsbC5wYWNrYWdlcygidGlkeWJheWVzIikKbGlicmFyeShiYXllc3Bsb3QpICAgICMgaW5zdGFsbC5wYWNrYWdlcygiYmF5ZXNwbG90IikKbGlicmFyeShtb2RlbHIpCmxpYnJhcnkoYnJvb20ubWl4ZWQpICAjIGluc3RhbGwucGFja2FnZXMoImJyb29tLm1peGVkIikKbGlicmFyeShicm1zKSAgICAgICAgICMgaW5zdGFsbC5wYWNrYWdlcygiYnJtcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdnb2thYmVpdG8pICAgIyBpbnN0YWxsLnBhY2thZ2VzKCJnZ29rYWJlaXRvIikKdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoKSkKCiMgQ3JlYXRpbmcgYSB0aGVtZSBmdW5jdGlvbiB1c2VkIGZvciB2aXN1YWxpemF0aW9ucwp0aGVtZV9jbGVhbiA8LSBmdW5jdGlvbigpIHsKICB0aGVtZV9taW5pbWFsKGJhc2VfZmFtaWx5ID0gIkFyaWFsIikgKwogICAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gcmVsKDEpLCBoanVzdCA9IDApLAogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gTkEpLAogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpKQp9CmBgYAoKIyBMb2FkaW5nIHRoZSBtb2RlbHMKYGBge3J9Cm1vZGVsX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfSW50LnJkcyIpCm1vZGVsX05hdCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfTmF0LnJkcyIpCm1vZGVsX2FydGljUmF0ZSA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfYXJ0aWNSYXRlLnJkcyIpCm1vZGVsX0FBVlMgPC0gYmFzZTo6cmVhZFJEUyhmaWxlID0gIk1vZGVscy9icm1zX0FBVlMucmRzIikKbW9kZWxfTTFzIDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJNb2RlbHMvYnJtc19NMXMucmRzIikKbW9kZWxfTTFzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfTTFzaC5yZHMiKQptb2RlbF9NMnMgPC0gYmFzZTo6cmVhZFJEUyhmaWxlID0gIk1vZGVscy9icm1zX00ycy5yZHMiKQptb2RlbF9NMnNoIDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJNb2RlbHMvYnJtc19NMnNoLnJkcyIpCmBgYAoKIyBGb3JtYXR0aW5nIGluZm8KYGBge3J9CnRleHRTaXplX3Bsb3RUaXRsZSA8LSA5CnRleHRTaXplX3Bsb3RTdWJ0aXRsZSA8LSA5CnRleHRTaXplX2F4aXNUaXRsZSA8LSA5CmBgYAoKIyAwMS4gUmVsaWFiaWxpdHkKYGBge3J9CndvcmtpbmdEYXRhX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9JbnQuUkRTIikKd29ya2luZ0RhdGFfTmF0IDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKQoKaW50ZXJSZWxfcGxvdERhdGEgPC0gcmJpbmQoCiAgd29ya2luZ0RhdGFfSW50JGRhdGEgJT4lCiAgICBkcGx5cjo6c2VsZWN0KGMoCiAgICAgIGdvcmlsbGFfaWQsCiAgICAgIHNwZWFrZXJfaWQsCiAgICAgIGBUaW1lIFBvaW50YCA9IHRpbWVfcG9pbnQsCiAgICAgIEdyb3VwID0gZ3JvdXAsCiAgICAgIFNleCA9IHNleCwKICAgICAgYWdlLAogICAgICByYXRpbmcKICAgICkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBNZWFzdXJlID0gIkludGVsbGlnaWJpbGl0eSIKICAgICksCiAgd29ya2luZ0RhdGFfTmF0JGRhdGEgJT4lCiAgICBkcGx5cjo6c2VsZWN0KGMoCiAgICAgIGdvcmlsbGFfaWQsCiAgICAgIHNwZWFrZXJfaWQsCiAgICAgIGBUaW1lIFBvaW50YCA9IHRpbWVfcG9pbnQsCiAgICAgIEdyb3VwID0gZ3JvdXAsCiAgICAgIFNleCA9IHNleCwKICAgICAgYWdlLAogICAgICByYXRpbmcKICAgICkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBNZWFzdXJlID0gIk5hdHVyYWxuZXNzIgogICAgKQopICU+JQogIGRwbHlyOjpmaWx0ZXIoZ29yaWxsYV9pZCAhPSAiMTAyMzc4NTEiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoc3BlYWtlcl9pZCwgYFRpbWUgUG9pbnRgLCBHcm91cCwgU2V4LCBhZ2UsIE1lYXN1cmUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoTSA9IG1lYW4ocmF0aW5nKSwKICAgICAgICAgICAgICAgICAgIHNkID0gc2QocmF0aW5nKSkgJT4lCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUKICBkcGx5cjo6bXV0YXRlKGBUaW1lIFBvaW50YCA9IGZhY3RvcihgVGltZSBQb2ludGAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZnRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkJlZm9yZSBTZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaXRoIFNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFmdGVyIFNlbnNvcnMiKSksCiAgICAgICAgICAgICAgICBNZWFzdXJlID0gZmFjdG9yKE1lYXN1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkludGVsbGlnaWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdHVyYWxuZXNzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkludGVsbGlnaWJpbGl0eSBSYXRpbmdzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0dXJhbG5lc3MgUmF0aW5ncyIpKSwKICAgICAgICAgICAgICAgIEdyb3VwID0gZmFjdG9yKEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQRCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQd1BEIikpKQoKaW50ZXJSZWxfcGxvdCA8LSBpbnRlclJlbF9wbG90RGF0YSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKAogICAgeCA9IE0sCiAgICB5ID0gc2QsCiAgICBjb2xvciA9IEdyb3VwLAogICAgc2hhcGUgPSBgVGltZSBQb2ludGAKICApICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofk1lYXN1cmUpICsKICBsYWJzKHggPSAiQXZlcmFnZSBSYXRpbmcgKE1lYW4pIiwKICAgICAgIHkgPSAiUmF0aW5nIFZhcmlhYmlsaXR5IChzZCkiLAogICAgICAgdGl0bGUgPSAiSW50ZXItbGlzdGVuZXIgUmVsaWFiaWxpdHkiLAogICAgICAgI3N1YnRpdGxlID0gIlRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgcmF0aW5ncyBhY3Jvc3Mgc3BlYWtlcnMgYW5kIHRpbWUgcG9pbnRzLiIKICAgICAgICkgKwogIGdnb2thYmVpdG86OnNjYWxlX2NvbG9yX29rYWJlX2l0byhvcmRlciA9IGMoMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIzUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICM0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKSkgKwogIGdndGhlbWVzOjp0aGVtZV9jbGVhbigpICYKICB0aGVtZSgKICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxMiksCiAgICBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICNwYW5lbC5tYXJnaW49dW5pdCguMDUsICJsaW5lcyIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEpLCAKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEpLAogICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEpLCAKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgbGVnZW5kLmJveD0idmVydGljYWwiLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSBOQSksCiAgICBhc3BlY3QucmF0aW8gPSAxKQoKaW50ZXJSZWxfcGxvdAoKZ2dzYXZlKHBsb3QgPSBpbnRlclJlbF9wbG90LAogICAgICAgZmlsZSA9ICJGaWd1cmVzL0ZpZ19JbnRlci1MaXN0ZW5lciBSZWxpYWJpbGl0eS5wbmciLAogICAgICAgaGVpZ2h0ID0gNSwKICAgICAgIHdpZHRoID0gNi41LAogICAgICAgdW5pdHMgPSAiaW4iLAogICAgICAgc2NhbGUgPSAxLAogICAgICAgYmcgPSAid2hpdGUiKQpgYGAKCiMgMDIuIEFydGljIFJhdGUKIyMgRXhwZWN0ZWQgUG9zdGVyaW9ycwpgYGB7cn0KIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfYXJ0aWNSYXRlIDwtIG1vZGVsX2FydGljUmF0ZSAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSA2Ni44OCwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKcGxvdF9ncmFuZE1lYW5fYXJ0aWNSYXRlIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9hcnRpY1JhdGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gLmVwcmVkLCB5ID0gdGltZV9wb2ludCwgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBhcnRpY3VsYXRpb24gcmF0ZSAoc3lsL3MpIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIGFydGljdWxhdGlvbiByYXRlIGFmdGVyXG5jb250cm9sbGluZyBmb3Igc3BlYWtlciBhZ2UgYW5kIHNleC4iKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICAjZmFjZXRfZ3JpZChzZXh+LikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpLAogICAgICAgICNwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleSIsIGZpbGwgPSBOQSkKICAgICAgICApICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfYXJ0aWNSYXRlIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX2FydGljUmF0ZS5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUgPC0gbW9kZWxfYXJ0aWNSYXRlICU+JQogIGVtbWVhbnM6OmVtbWVhbnMoIH4gdGltZV9wb2ludCB8IGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSwgKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfYXJ0aWNSYXRlICU+JQogIGVtbWVhbnM6OmVtbWVhbnMoIH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLCBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfYXJ0aWNSYXRlKQoKcGxvdF9SUTFfYXJ0aWNSYXRlIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX2FydGljUmF0ZSAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gInNlbnNvcnMgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBzZW5zb3JzIGVmZmVjdHMgKHN5bC9zKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfYXJ0aWNSYXRlCgpwbG90X1JRMl9hcnRpY1JhdGUgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfYXJ0aWNSYXRlICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBhZnRlci1zZW5zb3JcbmVmZmVjdHMgKHN5bC9zKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihjKSBSZXNlYXJjaCBRdWVzdGlvbiAyIiwKICAgIHN1YnRpdGxlID0gIkFmdGVyLXNlbnNvciBlZmZlY3QgKEFmdGVyIFNlbnNvcnMgLVxuQmVmb3JlIFNlbnNvcnMpIHBlciBncm91cCBhbmQgdGhlXG5lZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMl9hcnRpY1JhdGUKCiMgQ29tYmluZWQgcGxvdApwbG90X2FydGljUmF0ZSA8LSAgcGxvdF9ncmFuZE1lYW5fYXJ0aWNSYXRlICsgcGxvdF9SUTFfYXJ0aWNSYXRlICsgcGxvdF9SUTJfYXJ0aWNSYXRlICsKICBwYXRjaHdvcms6OnBsb3RfbGF5b3V0KG5jb2wgPSAzLCBoZWlnaHRzID0gYygxKSwgZ3VpZGVzID0gImNvbGxlY3QiCiAgICAgICAgICAgICAgICAgICAgICAgICApICsKICBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiQXJ0aWN1bGF0aW9uIFJhdGUiLCAjc3VidGl0bGUgPSAiUHJlZGljdGVkIGludGVsbGlnaWJpbGl0eSByYXRpbmdzIGFjcm9zcyBncm91cC9zZXZlcml0eSBhbmQgc3BlYWtpbmcgY29uZGl0aW9ucy4iLAogICAgICAgICAgICAgICAgICB0aGVtZSA9IHRoZW1lX2NsZWFuKCkpICYKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKcGxvdF9hcnRpY1JhdGUKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9hcnRpY1JhdGUsCiAgZmlsZW5hbWUgPSAiRmlndXJlcy9GaWdfYXJ0aWNSYXRlLnBuZyIsCiAgaGVpZ2h0ID0gNiwKICB3aWR0aCA9IDEwLAogIHVuaXQgPSAiaW4iLAogIHNjYWxlID0gLjksCiAgYmcgPSAid2hpdGUiCikKCmBgYAoKIyAwMy4gQUFWUwojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9BQVZTIDwtIG1vZGVsX0FBVlMgJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9BQVZTJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfQUFWUyRkYXRhJGFydGljX3JhdGUpLAogICAgKSwKICAgIHJlX2Zvcm11bGEgPSBOQQogICkgJT4lCiAgZ3JvdXBfYnkoLmRyYXcsIGdyb3VwLCB0aW1lX3BvaW50KSAlPiUKICBzdW1tYXJpemUoLmVwcmVkID0gbWVhbiguZXByZWQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgZ3JvdXAgPSBmYWN0b3IoCiAgICAgIGdyb3VwLAogICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiUHdQRCIpCiAgICApLAogICAgI2dyb3VwaW5nID0gcGFzdGUoc2V4LCBncm91cCwgc2VwID0gIiAtICIpLAogICAgI2dyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgIyAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWxlIC0gUHdQRCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gUHdQRCIpKSwKICAgIHRpbWVfcG9pbnQgPSBmYWN0b3IoCiAgICAgIHRpbWVfcG9pbnQsCiAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIGxhYmVscyA9IGMoIkJlZm9yZVxuU2Vuc29ycyIsICJXaXRoXG5TZW5zb3JzIiwgIkFmdGVyXG5TZW5zb3JzIikKICAgICkKICApCgpwbG90X2dyYW5kTWVhbl9BQVZTIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9BQVZTLCBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIGZpbGwgPSBncm91cCkpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIGdnb2thYmVpdG86OnNjYWxlX2ZpbGxfb2thYmVfaXRvKG9yZGVyID0gYygyLCAxKSkgKwogIGxhYnMoeCA9ICJQcmVkaWN0ZWQgQUFWUyAobWVswrIpIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIEFBVlMgYWZ0ZXIgY29udHJvbGxpbmcgZm9yXG5zcGVha2VyIGFnZSwgc2V4LCBhbmQgYXJ0aWN1bGF0aW9uIHJhdGUuIikgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYyguNjUsMSkpICsKICB0aGVtZV9jbGVhbigpICsKICAjZmFjZXRfZ3JpZChzZXh+LikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpLAogICAgICAgICNwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleSIsIGZpbGwgPSBOQSkKICAgICAgICApICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCnBsb3RfZ3JhbmRNZWFuX0FBVlMKYGBgCgojIyBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9BQVZTIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX0FBVlMuUkRTIikkcGFpcndpc2UgJT4lCiAgZHBseXI6OnNlbGVjdChjb250cmFzdCwgZ3JvdXAsIHJvYnVzdCkKCmRhdGFfbWVDb250cmFzdHNfQUFWUyA8LSBtb2RlbF9BQVZTICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpICAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgICBncm91cCA9PSAiQ29udHJvbCIgfiAiQ29udHJvbCIKICAgICkpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfQUFWUyAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikgICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICAgICkpCgpkYXRhX21lQ29udHJhc3RzX0FBVlMgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19BQVZTLCBpbnRlcmFjdGlvbl9jb250cmFzdCkgJT4lCiAgYmFzZTo6bWVyZ2UoLiwgcm9idXN0X0FBVlMpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICByb2J1c3QgPSBmYWN0b3Iocm9idXN0LCBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwgInJvYnVzdCIpKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX0FBVlMpCgpwbG90X1JRMV9BQVZTIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0FBVlMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJzZW5zb3JzIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAobWVswrIpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGIpIFJlc2VhcmNoIFF1ZXN0aW9uIDEiLAogICAgc3VidGl0bGUgPSAiU2Vuc29yIGVmZmVjdCAoV2l0aCBTZW5zb3JzIC0gQmVmb3JlIFNlbnNvcnMpXG5wZXIgZ3JvdXAgYW5kIHRoZSBlZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMV9BQVZTCgpwbG90X1JRMl9BQVZTIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0FBVlMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJhZnRlciAtIGJlZm9yZSIpLAogICAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIGFmdGVyLXNlbnNvclxuZWZmZWN0cyAobWVswrIpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX0FBVlMKCiMgQ29tYmluZWQgcGxvdApwbG90X0FBVlMgPC0gIHBsb3RfZ3JhbmRNZWFuX0FBVlMgKyBwbG90X1JRMV9BQVZTICsgcGxvdF9SUTJfQUFWUyArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywgaGVpZ2h0cyA9IGMoMSksIGd1aWRlcyA9ICJjb2xsZWN0IikgKwogIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJBcnRpY3VsYXRvcnkgQWNvdXN0aWMgVm93ZWwgU3BhY2UiLCAjc3VidGl0bGUgPSAiUHJlZGljdGVkIGludGVsbGlnaWJpbGl0eSByYXRpbmdzIGFjcm9zcyBncm91cC9zZXZlcml0eSBhbmQgc3BlYWtpbmcgY29uZGl0aW9ucy4iLAogICAgICAgICAgICAgICAgICB0aGVtZSA9IHRoZW1lX2NsZWFuKCkpICYKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKcGxvdF9BQVZTCgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfQUFWUywKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19BQVZTLnBuZyIsCiAgaGVpZ2h0ID0gNiwKICB3aWR0aCA9IDEwLAogIHVuaXQgPSAiaW4iLAogIHNjYWxlID0gLjksCiAgYmcgPSAid2hpdGUiCikKCmBgYAojIDA0LiBNMQojIyAvcy8gLSBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMXMgPC0gbW9kZWxfTTFzICU+JQogIHRpZHliYXllczo6ZXByZWRfZHJhd3MoCiAgICBuZXdkYXRhID0gdGlkeXI6OmV4cGFuZF9ncmlkKAogICAgICBncm91cCA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgdGltZV9wb2ludCA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIHNleCA9IGMoIk1hbGUiLCAiRmVtYWxlIiksCiAgICAgIGFnZSA9IG1lYW4obW9kZWxfTTFzJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTTFzJGRhdGEkYXJ0aWNfcmF0ZSksCiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKQogICkKCmBgYAoKIyMgL3MvIC0gTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTTFzIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX00xcy5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZGF0YV9tZUNvbnRyYXN0c19NMXMgPC0gbW9kZWxfTTFzICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfTTFzICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50ICogZ3JvdXAsIGVwcmVkID0gVFJVRSwgcmVfZm9ybXVsYSA9IE5BKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChpbnRlcmFjdGlvbiA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6OnJlbmFtZShjb250cmFzdCA9IHRpbWVfcG9pbnRfcmV2cGFpcndpc2UsCiAgICAgICAgICAgICAgICBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19NMXMgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19NMXMsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfTTFzKSAlPiUKICBkcGx5cjo6bXV0YXRlKHJvYnVzdCA9IGZhY3Rvcihyb2J1c3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibm90IHJvYnVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm9idXN0IikpKQoKI2JheWVzdGVzdFI6OnBfZGlyZWN0aW9uKGRhdGFfbWVDb250cmFzdHNfTTFzKQoKYGBgCgojIyAvc2gvIC0gRXhwZWN0ZWQgUG9zdGVyaW9ycwpgYGB7cn0KIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfTTFzaCA8LSBtb2RlbF9NMXNoICU+JQogIHRpZHliYXllczo6ZXByZWRfZHJhd3MoCiAgICBuZXdkYXRhID0gdGlkeXI6OmV4cGFuZF9ncmlkKAogICAgICBncm91cCA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgdGltZV9wb2ludCA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIHNleCA9IGMoIk1hbGUiLCAiRmVtYWxlIiksCiAgICAgIGFnZSA9IG1lYW4obW9kZWxfTTFzaCRkYXRhJGFnZSksCiAgICAgIGFydGljX3JhdGUgPSBtZWFuKG1vZGVsX00xc2gkZGF0YSRhcnRpY19yYXRlKSwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKYGBgCgojIyAvc2gvIC0gTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTTFzaCA8LSByaW86OmltcG9ydCgid29ya2luZ0RhdGEvZGF0YV9NMXNoLlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgpkYXRhX21lQ29udHJhc3RzX00xc2ggPC0gbW9kZWxfTTFzaCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCB8IGdyb3VwLAogICAgICAgICAgICAgICAgICAgZXByZWQgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QobWV0aG9kID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKIyBDb21wdXRlIHRoZSBpbnRlcmFjdGlvbiBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBjb250cmFzdHMgYmV0d2VlbiBncm91cHMpCmludGVyYWN0aW9uX2NvbnRyYXN0IDwtIG1vZGVsX00xc2ggJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgKiBncm91cCwgZXByZWQgPSBUUlVFLCByZV9mb3JtdWxhID0gTkEpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KGludGVyYWN0aW9uID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0ID0gdGltZV9wb2ludF9yZXZwYWlyd2lzZSwKICAgICAgICAgICAgICAgIGdyb3VwID0gZ3JvdXBfcmV2cGFpcndpc2UpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgpkYXRhX21lQ29udHJhc3RzX00xc2ggPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19NMXNoLCBpbnRlcmFjdGlvbl9jb250cmFzdCkgJT4lCiAgZHBseXI6Om11dGF0ZShncm91cCA9IGNhc2Vfd2hlbigKICAgIGdyb3VwID09ICJQRCIgfiAiUHdQRCIsCiAgICBncm91cCA9PSAiQ29udHJvbCIgfiAiQ29udHJvbCIsCiAgICBncm91cCA9PSAiUEQgLSBDb250cm9sIiB+ICJQd1BEIC1cbkNvbnRyb2wiCiAgKSkgJT4lCiAgYmFzZTo6bWVyZ2UoLiwgcm9idXN0X00xc2gpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMXNoKQoKYGBgCiMjIENvbWJpbmVkCiMjIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMSA8LSByYmluZChkYXRhX3Bvc3Rlcmlvcl9NMXMgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShzb3VuZCA9ICIvcy8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9wb3N0ZXJpb3JfTTFzaCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi/Kgy8iKSkKCnBsb3RfZ3JhbmRNZWFuX00xIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9NMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSAuZXByZWQsIHkgPSB0aW1lX3BvaW50LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBNMSAoa0h6KSIsIHkgPSBOVUxMLAogICAgICAgZmlsbCA9ICJHcm91cCIsCiAgICAgICB0aXRsZSA9ICIoYSkgUG9zdGVyaW9yIFByZWRpY3Rpb25zIiwKICAgICAgIHN1YnRpdGxlID0gIlByZWRpY3RlZCBNMSBhZnRlciBjb250cm9sbGluZyBmb3JcbnNwZWFrZXIgYWdlLCBzZXgsIGFuZCBhcnRpY3VsYXRpb24gcmF0ZS4iKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICBmYWNldF93cmFwKH5zb3VuZCwgbmNvbCA9IDEpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKSkgICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMjIE1FOiBUaW1lcG9pbnQgeCBHcm91cApgYGB7cn0KZGF0YV9tZUNvbnRyYXN0c19NMSA8LSByYmluZChkYXRhX21lQ29udHJhc3RzX00xcyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi9zLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX21lQ29udHJhc3RzX00xc2ggJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShzb3VuZCA9ICIvyoMvIikpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMSkKCnBsb3RfUlExX00xIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX00xICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAic2Vuc29ycyAtIGJlZm9yZSIpLAogIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBzZW5zb3JzIGVmZmVjdHMgKGtIeikiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYikgUmVzZWFyY2ggUXVlc3Rpb24gMSIsCiAgICBzdWJ0aXRsZSA9ICJTZW5zb3IgZWZmZWN0IChXaXRoIFNlbnNvcnMgLSBCZWZvcmUgU2Vuc29ycylcbnBlciBncm91cCBhbmQgdGhlIGVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgZmFjZXRfd3JhcCh+c291bmQsIG5jb2wgPSAxKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlExX00xCgpwbG90X1JRMl9NMSA8LSBnZ3Bsb3QoCiAgZGF0YV9tZUNvbnRyYXN0c19NMSAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gImFmdGVyIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIGFmdGVyLXNlbnNvclxuZWZmZWN0cyAoa0h6KSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihjKSBSZXNlYXJjaCBRdWVzdGlvbiAyIiwKICAgIHN1YnRpdGxlID0gIkFmdGVyLXNlbnNvciBlZmZlY3QgKEFmdGVyIFNlbnNvcnMgLVxuQmVmb3JlIFNlbnNvcnMpIHBlciBncm91cCBhbmQgdGhlXG5lZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGZhY2V0X3dyYXAofnNvdW5kLCBuY29sID0gMSkgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMl9NMQoKIyBDb21iaW5lZCBwbG90CnBsb3RfTTEgPC0gIHBsb3RfZ3JhbmRNZWFuX00xICsgcGxvdF9SUTFfTTEgKyBwbG90X1JRMl9NMSArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywgaGVpZ2h0cyA9IGMoMSksIGd1aWRlcyA9ICJjb2xsZWN0IikgKwogIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJTcGVjdHJhbCBDZW50ZXIgb2YgR3Jhdml0eSAoTTEpIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTTEKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9NMSwKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19NMS5wbmciLAogIGhlaWdodCA9IDcsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCiMgMDUuIE0yCiMjIC9zLyAtIEV4cGVjdGVkIFBvc3RlcmlvcnMKYGBge3J9CiMgR2VuZXJhdGUgZXhwZWN0ZWQgcHJlZGljdGlvbnMgZnJvbSB0aGUgcG9zdGVyaW9yCmRhdGFfcG9zdGVyaW9yX00ycyA8LSBtb2RlbF9NMnMgJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9NMnMkZGF0YSRhZ2UpLAogICAgICBhcnRpY19yYXRlID0gbWVhbihtb2RlbF9NMnMkZGF0YSRhcnRpY19yYXRlKSwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKYGBgCgojIyAvcy8gLSBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9NMnMgPC0gcmlvOjppbXBvcnQoIndvcmtpbmdEYXRhL2RhdGFfTTJzLlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgpkYXRhX21lQ29udHJhc3RzX00ycyA8LSBtb2RlbF9NMnMgJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgfCBncm91cCwKICAgICAgICAgICAgICAgICAgIGVwcmVkID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIHJlX2Zvcm11bGEgPSBOQSwpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KG1ldGhvZCA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCiMgQ29tcHV0ZSB0aGUgaW50ZXJhY3Rpb24gY29udHJhc3QgKGRpZmZlcmVuY2UgaW4gY29udHJhc3RzIGJldHdlZW4gZ3JvdXBzKQppbnRlcmFjdGlvbl9jb250cmFzdCA8LSBtb2RlbF9NMnMgJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgKiBncm91cCwgZXByZWQgPSBUUlVFLCByZV9mb3JtdWxhID0gTkEpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KGludGVyYWN0aW9uID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0ID0gdGltZV9wb2ludF9yZXZwYWlyd2lzZSwKICAgICAgICAgICAgICAgIGdyb3VwID0gZ3JvdXBfcmV2cGFpcndpc2UpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgpkYXRhX21lQ29udHJhc3RzX00ycyA8LSBiYXNlOjpyYmluZChkYXRhX21lQ29udHJhc3RzX00ycywgaW50ZXJhY3Rpb25fY29udHJhc3QpICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgZ3JvdXAgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiLAogICAgZ3JvdXAgPT0gIlBEIC0gQ29udHJvbCIgfiAiUHdQRCAtXG5Db250cm9sIgogICkpICU+JQogIGJhc2U6Om1lcmdlKC4sIHJvYnVzdF9NMnMpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMnMpCgpgYGAKCiMjIC9zaC8gLSBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMnNoIDwtIG1vZGVsX00yc2ggJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9NMnNoJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTTJzaCRkYXRhJGFydGljX3JhdGUpLAogICAgKSwKICAgIHJlX2Zvcm11bGEgPSBOQQogICkgJT4lCiAgZ3JvdXBfYnkoLmRyYXcsIGdyb3VwLCB0aW1lX3BvaW50KSAlPiUKICBzdW1tYXJpemUoLmVwcmVkID0gbWVhbiguZXByZWQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgZ3JvdXAgPSBmYWN0b3IoCiAgICAgIGdyb3VwLAogICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiUHdQRCIpCiAgICApLAogICAgI2dyb3VwaW5nID0gcGFzdGUoc2V4LCBncm91cCwgc2VwID0gIiAtICIpLAogICAgI2dyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgIyAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWxlIC0gUHdQRCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gUHdQRCIpKSwKICAgIHRpbWVfcG9pbnQgPSBmYWN0b3IoCiAgICAgIHRpbWVfcG9pbnQsCiAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIGxhYmVscyA9IGMoIkJlZm9yZVxuU2Vuc29ycyIsICJXaXRoXG5TZW5zb3JzIiwgIkFmdGVyXG5TZW5zb3JzIikKICAgICkKICApCgpgYGAKCiMjIC9zaC8gLSBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9NMnNoIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX00yc2guUkRTIikkcGFpcndpc2UgJT4lCiAgZHBseXI6OnNlbGVjdChjb250cmFzdCwgZ3JvdXAsIHJvYnVzdCkKCmRhdGFfbWVDb250cmFzdHNfTTJzaCA8LSBtb2RlbF9NMnNoICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfTTJzaCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCmRhdGFfbWVDb250cmFzdHNfTTJzaCA8LSBiYXNlOjpyYmluZChkYXRhX21lQ29udHJhc3RzX00yc2gsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfTTJzaCkgJT4lCiAgZHBseXI6Om11dGF0ZShyb2J1c3QgPSBmYWN0b3Iocm9idXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm5vdCByb2J1c3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJvYnVzdCIpKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX00yc2gpCgpgYGAKIyMgQ29tYmluZWQKIyMjIEV4cGVjdGVkIFBvc3RlcmlvcnMKYGBge3J9CiMgR2VuZXJhdGUgZXhwZWN0ZWQgcHJlZGljdGlvbnMgZnJvbSB0aGUgcG9zdGVyaW9yCmRhdGFfcG9zdGVyaW9yX00yIDwtIHJiaW5kKGRhdGFfcG9zdGVyaW9yX00ycyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi9zLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX3Bvc3Rlcmlvcl9NMnNoICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoc291bmQgPSAiL8qDLyIpKQoKcGxvdF9ncmFuZE1lYW5fTTIgPC0gZ2dwbG90KGRhdGFfcG9zdGVyaW9yX00yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gZ3JvdXApKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9maWxsX29rYWJlX2l0byhvcmRlciA9IGMoMiwgMSkpICsKICBsYWJzKHggPSAiUHJlZGljdGVkIE0yIChrSHopIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIE0yIGFmdGVyIGNvbnRyb2xsaW5nIGZvclxuc3BlYWtlciBhZ2UsIHNleCwgYW5kIGFydGljdWxhdGlvbiByYXRlLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIGZhY2V0X3dyYXAofnNvdW5kLCBuY29sID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpKSAgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkKYGBgCgojIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpkYXRhX21lQ29udHJhc3RzX00yIDwtIHJiaW5kKGRhdGFfbWVDb250cmFzdHNfTTJzICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoc291bmQgPSAiL3MvIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFfbWVDb250cmFzdHNfTTJzaCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi/Kgy8iKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX00yKQoKcGxvdF9SUTFfTTIgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfTTIgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJzZW5zb3JzIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAoa0h6KSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBmYWNldF93cmFwKH5zb3VuZCwgbmNvbCA9IDEpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfTTIKCnBsb3RfUlEyX00yIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX00yICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2YgYWZ0ZXItc2Vuc29yXG5lZmZlY3RzIChrSHopIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgZmFjZXRfd3JhcCh+c291bmQsIG5jb2wgPSAxKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX00yCgojIENvbWJpbmVkIHBsb3QKcGxvdF9NMiA8LSAgcGxvdF9ncmFuZE1lYW5fTTIgKyBwbG90X1JRMV9NMiArIHBsb3RfUlEyX00yICsKICBwYXRjaHdvcms6OnBsb3RfbGF5b3V0KG5jb2wgPSAzLCBoZWlnaHRzID0gYygxKSwgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIlNwZWN0cmFsIFN0YW5kYXJkIERldmlhdGlvbiAoTTIpIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTTIKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9NMiwKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19NMi5wbmciLAogIGhlaWdodCA9IDcsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCiMgMDYuIEludGVsbGlnaWJpbGl0eQojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQplcHNpbG9uIDwtIDFlLTUKIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfSW50IDwtIG1vZGVsX0ludCAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSBtZWFuKG1vZGVsX0ludCRkYXRhJGFnZSksICMgNjYuOTEgeW8KICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfSW50JGRhdGEkYXJ0aWNfcmF0ZSksICMgNC44NSBzeWwvcwogICAgICB0cmlhbF9udW1iZXIgPSBtZWFuKG1vZGVsX0ludCRkYXRhJHRyaWFsX251bWJlcikgIyB0cmlhbCA5CiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKSwKICAgIC5lcHJlZCA9ICguZXByZWQgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC5lcHJlZCA9IC5lcHJlZCAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC5lcHJlZCA9IC5lcHJlZCAqIDEwMCAjIHRvIHR1cm4gaXQgYmFjayB0byBhIHNjYWxlIG9mIDAgLSAxMDAKICApCgpwbG90X2dyYW5kTWVhbl9JbnQgPC0gZ2dwbG90KGRhdGFfcG9zdGVyaW9yX0ludCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSAuZXByZWQsIHkgPSB0aW1lX3BvaW50LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5nICglKSIsIHkgPSBOVUxMLAogICAgICAgZmlsbCA9ICJHcm91cCIsCiAgICAgICB0aXRsZSA9ICIoYSkgUG9zdGVyaW9yIFByZWRpY3Rpb25zIiwKICAgICAgIHN1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5nIGFmdGVyIGNvbnRyb2xsaW5nXG5mb3Igc3BlYWtlciBhZ2UsIHNleCwgYXJ0aWN1bGF0aW9uIHJhdGUsXG5hbmQgdHJpYWwgbnVtYmVyLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyg3MiwxMDApKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSksCiAgICAgICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJncmV5IiwgZmlsbCA9IE5BKQogICAgICAgICkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkKYGBgCgojIyBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9JbnQgPC0gcmlvOjppbXBvcnQoIndvcmtpbmdEYXRhL2RhdGFfSW50LlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgplcHNpbG9uIDwtIDFlLTUKZGF0YV9tZUNvbnRyYXN0c19JbnQgPC0gbW9kZWxfSW50ICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICAudmFsdWUgPSAoLnZhbHVlIC0gZXBzaWxvbikgLyAoMSAtIDIgKiBlcHNpbG9uKSwKICAgICMgU3RlcCAxICYgMjogUmV2ZXJzZSB0aGUgb2Zmc2V0IGFuZCBzY2FsaW5nCiAgICAudmFsdWUgPSAudmFsdWUgKiBucm93KC4pIC8gKChucm93KC4pIC0gMSkgKyAuNSksCiAgICAudmFsdWUgPSAudmFsdWUgKiAxMDAKICApICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfSW50ICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50ICogZ3JvdXAsIGVwcmVkID0gVFJVRSwgcmVfZm9ybXVsYSA9IE5BKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChpbnRlcmFjdGlvbiA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIC52YWx1ZSA9ICgudmFsdWUgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC52YWx1ZSA9IC52YWx1ZSAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC52YWx1ZSA9IC52YWx1ZSAqIDEwMAogICkgJT4lCiAgZHBseXI6OnJlbmFtZShjb250cmFzdCA9IHRpbWVfcG9pbnRfcmV2cGFpcndpc2UsCiAgICAgICAgICAgICAgICBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19JbnQgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19JbnQsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfSW50KSAlPiUKICBkcGx5cjo6bXV0YXRlKHJvYnVzdCA9IGZhY3Rvcihyb2J1c3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibm90IHJvYnVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm9idXN0IikpKQoKcGxvdF9SUTFfSW50IDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0ludCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gInNlbnNvcnMgLSBiZWZvcmUiKSwKICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgIyBUZXh0IGFubm90YXRpb24gZm9yIHRoZSBDb250cm9sIGFuZCBQd1BEIGRpc3RyaWJ1dGlvbnMKICBhbm5vdGF0ZSgKICAgICd0ZXh0JywKICAgIHggPSAtLjEzKjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMy4zLAogICAgbGFiZWwgPSAiQm90aCBDb250cm9sIGFuZCBQd1BEXG53ZXJlIHJvYnVzdGx5IGxlc3MgaW50ZWxsaWdiaWxlXG53aXRoIEVNQSBzZW5zb3JzIG9uLi4uIiwKICAgIGhqdXN0ID0gMCwKICAgIHNpemUgPSAyLAogICAgYWxwaGEgPSAuOCwKICAgIGNvbG9yID0gImJsYWNrIgogICkgKwogICMgQXJyb3cgdG8gdGhlIENvbnRyb2wgZGlzdHJpYnV0aW9uCiAgYW5ub3RhdGUoCiAgICAnY3VydmUnLAogICAgeCA9IC0uMDk1KjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMy4xLAogICAgeGVuZCA9IC0uMDMqMTAwLAogICAgeWVuZCA9IDIuOTYsCiAgICBsaW5ld2lkdGggPSAuNCwKICAgIGN1cnZhdHVyZSA9IDAuMiwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICdjbScpLCB0eXBlID0gImNsb3NlZCIpLAogICAgYWxwaGEgPSAxLAogICAgY29sb3IgPSAiZGFya2dyZXkiCiAgKSArCiAgIyBBcnJvdyB0byB0aGUgUHdQRCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICdjdXJ2ZScsCiAgICB4ID0gLS4wOTYqMTAwLCAjIFBsYXkgYXJvdW5kIHdpdGggdGhlIGNvb3JkaW5hdGVzIHVudGlsIHlvdSdyZSBzYXRpc2ZpZWQKICAgIHkgPSAzLjEsCiAgICB4ZW5kID0gLS4wNjUqMTAwLAogICAgeWVuZCA9IDIuMywKICAgIGxpbmV3aWR0aCA9IC40LAogICAgY3VydmF0dXJlID0gMC4yLAogICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMSwgJ2NtJyksIHR5cGUgPSAiY2xvc2VkIiksCiAgICBhbHBoYSA9IDEsCiAgICBjb2xvciA9ICJkYXJrZ3JleSIKICApICsKICAjIFRleHQgZm9yIHRoZSBjb250cmFzdCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICd0ZXh0JywKICAgIHggPSAtLjA3KjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMC43MywKICAgIGxhYmVsID0gIi4uLiBidXQgdGhlc2UgZWZmZWN0c1xud2VyZSByb2J1c3RseSBkaWZmZXJlbnRcbmJldHdlZW4gdGhlIGdyb3Vwcy4iLAogICAgaGp1c3QgPSAxLAogICAgc2l6ZSA9IDIsCiAgICBhbHBoYSA9IC44LAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgICAjIEFycm93IHRvIHRoZSBjb250cmFzdCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICdjdXJ2ZScsCiAgICB4ID0gLS4wNjUqMTAwLCAjIFBsYXkgYXJvdW5kIHdpdGggdGhlIGNvb3JkaW5hdGVzIHVudGlsIHlvdSdyZSBzYXRpc2ZpZWQKICAgIHkgPSAwLjczLAogICAgeGVuZCA9IC0uMDQ1KjEwMCwKICAgIHllbmQgPSAuOTUsCiAgICBsaW5ld2lkdGggPSAuNCwKICAgIGN1cnZhdHVyZSA9IDAuMiwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICdjbScpLCB0eXBlID0gImNsb3NlZCIpLAogICAgYWxwaGEgPSAxLAogICAgY29sb3IgPSAiZGFya2dyZXkiCiAgKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2Ygc2Vuc29ycyBlZmZlY3RzICglKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfSW50CgpwbG90X1JRMl9JbnQgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfSW50ICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBhZnRlci1zZW5zb3JcbmVmZmVjdHMgKCUpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX0ludAoKIyBDb21iaW5lZCBwbG90CnBsb3RfSW50IDwtICBwbG90X2dyYW5kTWVhbl9JbnQgKyBwbG90X1JRMV9JbnQgKyBwbG90X1JRMl9JbnQgKwogIHBhdGNod29yazo6cGxvdF9sYXlvdXQobmNvbCA9IDMsIGhlaWdodHMgPSBjKDEpLCBndWlkZXMgPSAiY29sbGVjdCIpICsKICBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiSW50ZWxsaWdpYmlsaXR5IiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfSW50CgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfSW50LAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvRmlnX0ludC5wbmciLAogIGhlaWdodCA9IDYsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCgojIDA3LiBOYXR1cmFsbmVzcwojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQplcHNpbG9uIDwtIDFlLTUKIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfTmF0IDwtIG1vZGVsX05hdCAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSBtZWFuKG1vZGVsX05hdCRkYXRhJGFnZSksICMgNjYuOTEgeW8KICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTmF0JGRhdGEkYXJ0aWNfcmF0ZSksICMgNC44NSBzeWwvcwogICAgICB0cmlhbF9udW1iZXIgPSBtZWFuKG1vZGVsX05hdCRkYXRhJHRyaWFsX251bWJlcikgIyB0cmlhbCA5CiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKSwKICAgIC5lcHJlZCA9ICguZXByZWQgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC5lcHJlZCA9IC5lcHJlZCAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC5lcHJlZCA9IC5lcHJlZCAqIDEwMAogICkKCnBsb3RfZ3JhbmRNZWFuX05hdCA8LSBnZ3Bsb3QoZGF0YV9wb3N0ZXJpb3JfTmF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gZ3JvdXApKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9maWxsX29rYWJlX2l0byhvcmRlciA9IGMoMiwgMSkpICsKICBsYWJzKHggPSAiUHJlZGljdGVkIG5hdHVyYWxuZXNzIHJhdGluZyAoJSkiLCB5ID0gTlVMTCwKICAgICAgIGZpbGwgPSAiR3JvdXAiLAogICAgICAgdGl0bGUgPSAiKGEpIFBvc3RlcmlvciBQcmVkaWN0aW9ucyIsCiAgICAgICBzdWJ0aXRsZSA9ICJQcmVkaWN0ZWQgbmF0dXJhbG5lc3MgcmF0aW5nIGFmdGVyIGNvbnRyb2xsaW5nXG5mb3Igc3BlYWtlciBhZ2UsIHNleCwgYXJ0aWN1bGF0aW9uIHJhdGUsXG5hbmQgdHJpYWwgbnVtYmVyLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKSkgICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTmF0IDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZXBzaWxvbiA8LSAxZS01CmRhdGFfbWVDb250cmFzdHNfTmF0IDwtIG1vZGVsX05hdCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCB8IGdyb3VwLAogICAgICAgICAgICAgICAgICAgZXByZWQgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QobWV0aG9kID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgLnZhbHVlID0gKC52YWx1ZSAtIGVwc2lsb24pIC8gKDEgLSAyICogZXBzaWxvbiksCiAgICAjIFN0ZXAgMSAmIDI6IFJldmVyc2UgdGhlIG9mZnNldCBhbmQgc2NhbGluZwogICAgLnZhbHVlID0gLnZhbHVlICogbnJvdyguKSAvICgobnJvdyguKSAtIDEpICsgLjUpLAogICAgLnZhbHVlID0gLnZhbHVlICogMTAwCiAgKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKIyBDb21wdXRlIHRoZSBpbnRlcmFjdGlvbiBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBjb250cmFzdHMgYmV0d2VlbiBncm91cHMpCmludGVyYWN0aW9uX2NvbnRyYXN0IDwtIG1vZGVsX05hdCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICAudmFsdWUgPSAoLnZhbHVlIC0gZXBzaWxvbikgLyAoMSAtIDIgKiBlcHNpbG9uKSwKICAgICMgU3RlcCAxICYgMjogUmV2ZXJzZSB0aGUgb2Zmc2V0IGFuZCBzY2FsaW5nCiAgICAudmFsdWUgPSAudmFsdWUgKiBucm93KC4pIC8gKChucm93KC4pIC0gMSkgKyAuNSksCiAgICAudmFsdWUgPSAudmFsdWUgKiAxMDAKICApICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCmRhdGFfbWVDb250cmFzdHNfTmF0IDwtIGJhc2U6OnJiaW5kKGRhdGFfbWVDb250cmFzdHNfTmF0LCBpbnRlcmFjdGlvbl9jb250cmFzdCkgICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgZ3JvdXAgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiLAogICAgZ3JvdXAgPT0gIlBEIC0gQ29udHJvbCIgfiAiUHdQRCAtXG5Db250cm9sIgogICkpICU+JQogIGJhc2U6Om1lcmdlKC4sIHJvYnVzdF9OYXQpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19OYXQpCgpwbG90X1JRMV9OYXQgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfTmF0ICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAic2Vuc29ycyAtIGJlZm9yZSIpLAogICAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAoJSkiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYikgUmVzZWFyY2ggUXVlc3Rpb24gMSIsCiAgICBzdWJ0aXRsZSA9ICJTZW5zb3IgZWZmZWN0IChXaXRoIFNlbnNvcnMgLSBCZWZvcmUgU2Vuc29ycylcbnBlciBncm91cCBhbmQgdGhlIGVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlExX05hdAoKcGxvdF9SUTJfTmF0IDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX05hdCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gImFmdGVyIC0gYmVmb3JlIiksCiAgICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2YgYWZ0ZXItc2Vuc29yc1xuZWZmZWN0cyAoJSkiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYykgUmVzZWFyY2ggUXVlc3Rpb24gMiIsCiAgICBzdWJ0aXRsZSA9ICJBZnRlci1zZW5zb3IgZWZmZWN0IChBZnRlciBTZW5zb3JzIC1cbkJlZm9yZSBTZW5zb3JzKSBwZXIgZ3JvdXAgYW5kIHRoZVxuZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTJfTmF0CgojIENvbWJpbmVkIHBsb3QKcGxvdF9OYXQgPC0gIHBsb3RfZ3JhbmRNZWFuX05hdCArIHBsb3RfUlExX05hdCArIHBsb3RfUlEyX05hdCArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywKICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodHMgPSBjKDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIk5hdHVyYWxuZXNzIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTmF0CgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfTmF0LAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvRmlnX05hdC5wbmciLAogIGhlaWdodCA9IDYsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKIyBTMDEuIEluZGl2aWR1YWwgVmFyaWFiaWxpdHkKYGBge3J9CndvcmtpbmdEYXRhX2FydGljUmF0ZSA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9hcnRpY1JhdGUuUkRTIikKd29ya2luZ0RhdGFfQUFWUyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9BQVZTLlJEUyIpCndvcmtpbmdEYXRhX00xcyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMXMuUkRTIikKd29ya2luZ0RhdGFfTTFzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMXNoLlJEUyIpCndvcmtpbmdEYXRhX00ycyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMnMuUkRTIikKd29ya2luZ0RhdGFfTTJzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMnNoLlJEUyIpCndvcmtpbmdEYXRhX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9JbnQuUkRTIikKd29ya2luZ0RhdGFfTmF0IDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKQoKYWxsRGF0YSA8LSBiaW5kX3Jvd3MoCiAgd29ya2luZ0RhdGFfYXJ0aWNSYXRlJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJBcnRpY3VsYXRpb24gUmF0ZSIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IGFydGljUmF0ZSksCiAgCiAgd29ya2luZ0RhdGFfQUFWUyRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiQUFWUyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IEFBVlMpLAogIAogIHdvcmtpbmdEYXRhX00xcyRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiTTEgZm9yIC9zLyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IE0xcyksCiAgCiAgd29ya2luZ0RhdGFfTTJzJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJNMiBmb3IgL3MvIikgJT4lCiAgICBkcGx5cjo6cmVuYW1lKHZhbHVlID0gTTJzKSwKICAKICB3b3JraW5nRGF0YV9NMXNoJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJNMSBmb3IgL8qDLyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IE0xc2gpLAogIAogIHdvcmtpbmdEYXRhX00yc2gkbW9kZWxEYXRhICU+JQogICAgZHBseXI6Om11dGF0ZShtZWFzdXJlID0gIk0yIGZvciAvyoMvIikgJT4lCiAgICBkcGx5cjo6cmVuYW1lKHZhbHVlID0gTTJzaCksCiAgCiAgd29ya2luZ0RhdGFfSW50JG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJJbnRlbGxpZ2liaWxpdHkiLAogICAgICAgICAgICAgICAgICBJbnQgPSBJbnQqMTAwKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUodmFsdWUgPSBJbnQpLAogIAogIHdvcmtpbmdEYXRhX05hdCRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiTmF0dXJhbG5lc3MiLAogICAgICAgICAgICAgICAgICBOYXQgPSBOYXQqMTAwKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUodmFsdWUgPSBOYXQpCikgJT4lCiAgZHBseXI6Om11dGF0ZSh0aW1lX3BvaW50ID0gZmFjdG9yKHRpbWVfcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZnRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaXRoXG5TZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWZ0ZXJcblNlbnNvcnMiKSksCiAgICAgICAgICAgICAgICBtZWFzdXJlID0gZmFjdG9yKG1lYXN1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkFydGljdWxhdGlvbiBSYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUFWUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk0xIGZvciAvcy8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMiBmb3IgL3MvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTEgZm9yIC/Kgy8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMiBmb3IgL8qDLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVsbGlnaWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdHVyYWxuZXNzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkFydGljdWxhdGlvbiBSYXRlIChzeWwvcykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQVZTIChtZWzCsikiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMSBmb3IgL3MvIChrSHopIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTIgZm9yIC9zLyAoa0h6KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk0xIGZvciAvyoMvIChrSHopIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTIgZm9yIC/Kgy8gKGtIeikiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnRlbGxpZ2liaWxpdHkgKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0dXJhbG5lc3MgKCUpIikpLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBmYWN0b3IoZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBEIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlB3UEQiKSksCiAgICAgICAgICAgICAgICBncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkobWVhc3VyZSwgc3BlYWtlcl9pZCwgZ3JvdXAsIHNleCwgZ3JvdXBpbmcsIGFnZSwgdGltZV9wb2ludCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBkcGx5cjo6dW5ncm91cCgpCgpwbG90RGF0YSA8LSBiaW5kX3Jvd3MoCiAgYWxsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUocGxvdCA9ICJBbGwgRGF0YSIpLAogIGFsbERhdGEgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKHRpbWVfcG9pbnQgIT0gIkFmdGVyXG5TZW5zb3JzIikgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBsb3QgPSAiU2Vuc29yIEVmZmVjdHMiKSwKICBhbGxEYXRhICU+JQogICAgZHBseXI6OmZpbHRlcih0aW1lX3BvaW50ICE9ICJXaXRoXG5TZW5zb3JzIikgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBsb3QgPSAiQWZ0ZXItU2Vuc29yIEVmZmVjdHMiKSwKKSAlPiUKICBkcGx5cjo6bXV0YXRlKHBsb3QgPSBmYWN0b3IocGxvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiQWxsIERhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5zb3IgRWZmZWN0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFmdGVyLVNlbnNvciBFZmZlY3RzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkFsbCBEYXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2Vuc29yIEVmZmVjdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZnRlci1TZW5zb3JcbkVmZmVjdHMiKSkpICU+JQogIGRwbHlyOjpmaWx0ZXIocGxvdCAhPSAiQWxsIERhdGEiKQoKcGxvdF9yYXdEYXRhX3NlbnNvckVmZmVjdHMgPC0gcGxvdERhdGEgJT4lCiAgZHBseXI6OmZpbHRlcihwbG90ID09ICJTZW5zb3IgRWZmZWN0cyIpICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHRpbWVfcG9pbnQsIHkgPSB2YWx1ZSwgY29sb3IgPSBncm91cCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzcGVha2VyX2lkKSwgYWxwaGEgPSAuMykgKwogIGdlb21fbGluZSgKICAgIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgZHBseXI6OmZpbHRlcihwbG90ID09ICJTZW5zb3IgRWZmZWN0cyIpICU+JQogICAgICBkcGx5cjo6Z3JvdXBfYnkobWVhc3VyZSwgZ3JvdXAsIHNleCwgdGltZV9wb2ludCwgcGxvdCkgJT4lCiAgICAgIGRwbHlyOjpzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSksCiAgICBhZXMoZ3JvdXAgPSBncm91cCksCiAgICBhbHBoYSA9IC44LAogICAgbGluZXdpZHRoID0gMS41CiAgKSArCiAgI2dlb21fcG9pbnQoYWVzKHNoYXBlID0gc2V4KSkgKwogIGdnb2thYmVpdG86OnNjYWxlX2NvbG9yX29rYWJlX2l0byhvcmRlciA9IGMoMiwxKSkgKwogIGZhY2V0X2dyaWQobWVhc3VyZSB+IHNleCwgc2NhbGVzID0gImZyZWUiLCBzd2l0Y2ggPSAieSIpICsKICBsYWJzKHggPSBOVUxMLAogICAgICAgeSA9IE5VTEwsCiAgICAgICBjb2xvciA9ICJHcm91cCIsCiAgICAgICBzaGFwZSA9ICJTZXgiLAogICAgICAgdGl0bGUgPSAiU2Vuc29yIEVmZmVjdHMiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShleHBhbmQ9ZXhwYW5zaW9uKGMoLjM1LC4zNSkpKSArCiAgdGhlbWVfY2xlYW4oKSAmCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSAiYmxhY2siKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsCiAgICAgICAgc3RyaXAudGV4dC55LmxlZnQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBmYWNlPSJwbGFpbiIsIGhqdXN0ID0gMSksKQpwbG90X3Jhd0RhdGFfc2Vuc29yRWZmZWN0cwoKcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cyA8LSBwbG90RGF0YSAlPiUKICBkcGx5cjo6ZmlsdGVyKHBsb3QgPT0gIkFmdGVyLVNlbnNvclxuRWZmZWN0cyIpICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHRpbWVfcG9pbnQsIHkgPSB2YWx1ZSwgY29sb3IgPSBncm91cCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzcGVha2VyX2lkKSwgYWxwaGEgPSAuMykgKwogIGdlb21fbGluZSgKICAgIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgZHBseXI6OmZpbHRlcihwbG90ID09ICJBZnRlci1TZW5zb3JcbkVmZmVjdHMiKSAlPiUKICAgICAgZHBseXI6Omdyb3VwX2J5KG1lYXN1cmUsIGdyb3VwLCBzZXgsIHRpbWVfcG9pbnQsIHBsb3QpICU+JQogICAgICBkcGx5cjo6c3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSkpLAogICAgYWVzKGdyb3VwID0gZ3JvdXApLAogICAgYWxwaGEgPSAuOCwKICAgIGxpbmV3aWR0aCA9IDEuNQogICkgKwogICNnZW9tX3BvaW50KGFlcyhzaGFwZSA9IHNleCkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9jb2xvcl9va2FiZV9pdG8ob3JkZXIgPSBjKDIsMSkpICsKICBmYWNldF9ncmlkKG1lYXN1cmUgfiBzZXgsIHNjYWxlcyA9ICJmcmVlIikgKwogIGxhYnMoeCA9IE5VTEwsCiAgICAgICB5ID0gTlVMTCwKICAgICAgIGNvbG9yID0gIkdyb3VwIiwKICAgICAgIHNoYXBlID0gIlNleCIsCiAgICAgICB0aXRsZSA9ICJBZnRlci1TZW5zb3IgRWZmZWN0cyIpICsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZD1leHBhbnNpb24oYyguMzUsLjM1KSkpICsKICB0aGVtZV9jbGVhbigpICYKICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9ICJibGFjayIpLAogICAgICAgICNzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsCiAgICAgICAgI3N0cmlwLnRleHQueS5sZWZ0ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgZmFjZT0icGxhaW4iLCBoanVzdCA9IDEpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC55LiA9IGVsZW1lbnRfYmxhbmsoKSkKcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cwoKcGxvdF9yYXdEYXRhIDwtIHBsb3RfcmF3RGF0YV9zZW5zb3JFZmZlY3RzICsgcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cyArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMiwgI2hlaWdodHMgPSBjKDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIlJhdyBEYXRhIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgc3RyaXAuYmFja2dyb3VuZC5yaWdodCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHN0cmlwLnRleHQueS5yaWdodCA9IGVsZW1lbnRfYmxhbmsoKQogICkKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9yYXdEYXRhLAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvU3VwRmlnX3Jhd0RhdGEucG5nIiwKICBoZWlnaHQgPSAxMCwKICB3aWR0aCA9IDksCiAgdW5pdCA9ICJpbiIsCiAgc2NhbGUgPSAuOSwKICBiZyA9ICJ3aGl0ZSIKKQpgYGAKCg==